namespace FIREFLYX {
    /** 渲染加载模型 */
    export class LoadModel implements IExample {
        public async Init(canvas: HTMLCanvasElement) {
            const gl = canvas.getContext("webgl2");
            //app init
            App.init(gl.canvas as any);
            //简单观察相机
            const cVEnv = GenCamViewEnv();
            const cam = cVEnv.camera;
            cVEnv.camHover.distance = 20;

            let cubeMap1 = await LoadCubeMapByHtmlImages(`01`, `.hi.jpg`);
            AttachSkyBox(cubeMap1);
            cam.clearMode = CameraClearMode.SKY_BOX;    //相机设置 SKY_BOX

            //模型节点
            const model = new GameObject("model");
            model.transform.scale = new Vector3(2, 2, 2);
            model.transform.position = new Vector3(2, 0, 2);
            const mr = model.addComponent<MeshRenderer>(MeshRenderer);
            // FIREFLYX.Quaternion.RotationAlphaBetaGammaToRef(0,0.2,0,entity.transform.rotation);

            //点状方向光源
            const light = GenMainLight();

            //加载组装一个 .obj 模型
            const isLoadObj = false;
            if (isLoadObj) {
                //光斑大小（大于0）
                const spotSpec = 1000;
                //资源准备
                //加载 OBJ 格式模型
                const oBJUrl = `res/OBJs/box1/box1.obj`;
                const mesh = await AssetManager.LoadFile(oBJUrl) as Mesh;
                //纹理
                // const tex = DefaultAsset.GetTexture(DefTexture.Grid);
                const texUrl = `res/OBJs/box1/Image_3.png`;
                const tex = await AssetManager.LoadFile(texUrl) as Texture2D;

                //加载 Unlit/colorTex shader
                const shUrl = `res/shaders/colorTex.shader.json`;
                const sh = await AssetManager.LoadFile(shUrl) as Shader;
                if (!sh.isLoadedAll()) await sh.loadAllFile();
                sh.apply();
                //-----shader enable keyword-------
                Shader.enableKeyword("RED");
                // sh.enableKeyword("GREEN");
                // sh.enableKeyword("BLUE");
                //disable keyword
                // sh.disableKeyword("RED");
                // sh.disableKeyword("GREEN");
                // sh.disableKeyword("BLUE");
                //---------------------------------

                //引擎内建 shader
                const bSh = DefaultAsset.GetShader(FIREFLYX.BUILTIN_SHADER_BUMPED_SPECULAR);

                //设置 renderer
                mr.mesh = mesh;
                const mainMtr = new Material();
                mr.materialGroup.push(mainMtr);
                //设置材质
                // mainMtr.shader = bSh;
                mainMtr.shader = sh;
                mainMtr.setProperty(`u_mainColor`, new Color4(1, 1, 1, 1));
                mainMtr.setProperty(`ubo_material_block.u_spotSpec`, spotSpec);
                mainMtr.setProperty(`u_mainTex`, tex);

                //-----Material enable keyword-------
                // mainMtr.enableKeyword("RED");
                // sh.enableKeyword("GREEN");
                mainMtr.enableKeyword("BLUE");
                //disable keyword
                // mainMtr.disableKeyword("RED");
                // mainMtr.disableKeyword("GREEN");
                // mainMtr.disableKeyword("BLUE");
                //---------------------------------

            }

            //加载组装一个 gltf 模型
            const loadGLTF = true;
            if (loadGLTF) {
                //加载 GLTF 格式模型
                const gltfUrl = `res/gltfs/drill_soviet/scene.gltf`;
                const dsGLTF = await AssetManager.LoadFile(gltfUrl) as GLTF;
                // const dsModel = await dsGLTF.getGameObjectAsync();
                // const dsScale = dsModel.transform.localScale;
                // dsModel.transform.localScale = dsScale.scale(100);

                // const gltfMesh = AssetManager.GetAsset(`res/gltfs/drill_soviet/SM_Drill_01_LOD0_M_Drill_01_0`) as Mesh;
                // debugger;

                // mesh = DefaultAsset.GetMesh(DefMesh.SPHERE);
                // mesh = gltfMesh;

                //加载 二级制 GLTF 格式模型
                const glbUrl = `res/gltfs/BoomBox.glb`;
                // const glbUrl = `res/gltfs/AlphaBlendModeTest.glb`;
                // const glbUrl = `res/gltfs/NegativeScaleTest.glb`;
                // const glbUrl = `res/gltfs/DamagedHelmet.glb`;
                // const glbUrl = `res/gltfs/MetalRoughSpheresNoTextures.glb`;
                // const glbUrl = `res/gltfs/MorphPrimitivesTest.glb`;
                // const glbUrl = `res/gltfs/MorphStressTest.glb`;
                // const glbUrl = `res/gltfs/MultiUVTest.glb`;
                const dsGLB = await AssetManager.LoadFile(glbUrl) as GLTF;
                const dsModelGLB = await dsGLB.getGameObjectAsync();
                const dsScaleGLB = dsModelGLB.transform.localScale;
                dsModelGLB.transform.localScale = dsScaleGLB.scale(300);
                // dsModelGLB.transform.localScale = dsScaleGLB.scale(1);
            }

            const angles = new Vector3(20 * toRadian, 30 * toRadian);
            //监听 场景循环更新
            GlobalEventManager.Instance.addListener("sceneUpdate", (dt: number) => {
                //
                // //计算 光源方向
                // light.transform.rotation.toEulerAnglesToRef(lightDir, "xyz");
                //旋转
                // Quaternion.RotationYawPitchRollToRef(angles.y, angles.x, angles.z, model.transform.rotation);
                const lightNode = light.entity;
                Quaternion.RotationYawPitchRollToRef(angles.y, angles.x, angles.z, lightNode.transform.rotation);
                lightNode.transform.rotation = lightNode.transform.rotation;
            }, this);

            //IO Event
            //键盘控制旋转
            let speed = 0.1;
            GlobalEventManager.Instance.addListener("keydown", (ev: KeyboardEvent) => {
                console.log(`onkeydown : ${ev.key} `);
                const dt = 1 * speed;
                switch (ev.key) {
                    case "a": angles.x += dt; break;
                    case "w": angles.y += dt; break;
                    default:
                }
            }, this);
        }
    }
}